package me.gavin.widget

import android.view.View
import androidx.databinding.BaseObservable
import androidx.databinding.ObservableField
import androidx.databinding.ObservableInt
import androidx.recyclerview.widget.RecyclerView
import me.gavin.R
import me.gavin.base.Gavin

/**
 * 下拉加载更多 ViewModel
 *
 * @author gavin.xiong 2018/9/3 0003
 */
class PagerViewModel constructor(
        private val recycler: RecyclerView?,
        private val list: List<*>?,
        private val headerLoadEnable: Boolean = true,
        private val footerLoadEnable: Boolean = true,
        private val callback: (() -> Unit)? = null
) : BaseObservable() {

    /**
     * RecyclerView 自动加载更多触发器
     */
    private val onScrollListener = object : RecyclerView.OnScrollListener() {
        override fun onScrolled(recycler: RecyclerView, dx: Int, dy: Int) {
            recycler.layoutManager?.apply {
                getChildAt(childCount - 1)?.let {
                    if (getPosition(it) > itemCount - 2 - pagingPreCount) {
                        performPagingLoad()
                    }
                }
            }
            // 距离是根据可见区域item高度目测的
            // if (!recycler.canScrollVertically(1)) {
            //     performPagingLoad()
            // }
            // 滑动到最底部时停止惯性
            if (!recycler.canScrollVertically(1)) {
                recycler.stopScroll()
            }
        }
    }

    init {
        if (footerLoadEnable) {
            recycler?.addOnScrollListener(onScrollListener)
        }
    }

    val headerIvVisible = ObservableInt(View.GONE)
    val headerPbVisible = ObservableInt(View.GONE)
    val headerTvVisible = ObservableInt(View.GONE)
    val headerTvText = ObservableField<String>("发呆中")
    val headerBtnVisible = ObservableInt(View.GONE)
    val headerBtnText = ObservableField<String>("TODO")

    val footerPbVisible = ObservableInt(View.GONE)
    val footerTvVisible = ObservableInt(View.GONE)
    val footerTvText = ObservableField<String>("发呆中")


    private var pagingLoading = false   // 分页数据加载中
    private val pagingPreCount = 1      // 分页数据预加载触发数量
    var pagingHaveMore = false          // 有无更多
    val pagingLimit = 20                // 分页数据大小
    var pagingOffset = 1                // 分页页码
        private set

    fun offset(isMore: Boolean) = if (isMore) ++pagingOffset else 1

//    fun <T> apply(isMore: Boolean, emptyHint: String? = null, emptyBtnTxt: String? = null): SingleTransformer<T, T> {
//        list!!
//        recycler!!
//
//        return SingleTransformer { upstream ->
//            upstream.doOnSubscribe {
//                pagingLoading = true
//
//                if (!isMore) {
//                    pagingOffset = 1
//
//                    headerIvVisible.set(if (headerLoadEnable && list.isEmpty()) View.INVISIBLE else View.GONE)
//                    headerPbVisible.set(if (headerLoadEnable && list.isEmpty()) View.VISIBLE else View.GONE)
//                    headerTvVisible.set(View.GONE)
//                    headerBtnVisible.set(View.GONE)
//                    footerPbVisible.set(View.GONE)
//                    footerTvVisible.set(View.GONE)
//                } else {
//                    headerIvVisible.set(View.GONE)
//                    headerPbVisible.set(View.GONE)
//                    headerTvVisible.set(View.GONE)
//                    headerBtnVisible.set(View.GONE)
//                    footerPbVisible.set(View.VISIBLE)
//                    footerTvVisible.set(View.VISIBLE)
//                    footerTvText.set(Gavin.app.getString(R.string.label_loading_loading))
//                }
//            }.doAfterSuccess {
//                pagingLoading = false
//
//                headerIvVisible.set(if (list.isEmpty()) View.VISIBLE else View.GONE)
//                headerPbVisible.set(View.GONE)
//                headerTvVisible.set(headerIvVisible.get())
//                headerTvText.set(emptyHint ?: Gavin.app.getString(R.string.label_loading_empty))
//                headerBtnVisible.set(if (list.isEmpty() && emptyBtnTxt != null) View.VISIBLE else View.GONE)
//                headerBtnText.set(emptyBtnTxt)
//                footerPbVisible.set(View.GONE)
//                footerTvVisible.set(if (footerLoadEnable && list.isNotEmpty()) View.VISIBLE else View.GONE)
//                footerTvText.set(Gavin.app.getString(if (pagingHaveMore) R.string.label_loading_idle else R.string.label_loading_period))
//
//                // 如果当前已不可向上滑动 - 尝试加载更多 - 解决分页加载不满一屏时无法滑动问题
//                if (footerLoadEnable && pagingHaveMore) {
//                    recycler.layoutManager?.apply {
//                        if (childCount > itemCount - 1 - pagingPreCount) {
//                            performPagingLoad()
//                        }
//                    }
//                }
//            }.doOnError {
//                pagingLoading = false
//                pagingOffset--
//
//                headerIvVisible.set(if (list.isEmpty()) View.VISIBLE else View.GONE)
//                headerPbVisible.set(View.GONE)
//                headerTvVisible.set(headerIvVisible.get())
//                headerTvText.set(Gavin.app.getString(R.string.label_loading_error))
//                // todo headerBtnVisible.set(View.GONE) 重试？
//                footerPbVisible.set(View.GONE)
//                footerTvVisible.set(if (footerLoadEnable && list.isNotEmpty()) View.VISIBLE else View.GONE)
//                footerTvText.set(Gavin.app.getString(R.string.label_loading_error))
//            }
//        }
//    }

    fun notifyClear() {
        headerIvVisible.set(View.GONE)
        headerPbVisible.set(View.GONE)
        headerTvVisible.set(View.GONE)
        headerBtnVisible.set(View.GONE)
        footerPbVisible.set(View.GONE)
        footerTvVisible.set(View.GONE)
    }

    fun notifyEmpty(emptyHint: String? = null, emptyBtnTxt: String? = null) {
        headerIvVisible.set(View.VISIBLE)
        headerPbVisible.set(View.GONE)
        headerTvVisible.set(View.VISIBLE)
        headerTvText.set(emptyHint ?: Gavin.app.getString(R.string.label_loading_empty))
        headerBtnVisible.set(if (emptyBtnTxt != null) View.VISIBLE else View.GONE)
        headerBtnText.set(emptyBtnTxt)
        footerPbVisible.set(View.GONE)
        footerTvVisible.set(View.GONE)
        footerTvText.set(Gavin.app.getString(R.string.label_loading_empty))
    }

    fun notifyDataSetChanged() {
        if (list?.isEmpty() != false) {
            notifyEmpty()
        } else {
            notifyClear()
        }
    }

    var action: (() -> Unit)? = null

    fun onActionClick() {
        action?.invoke()
    }

    /**
     * 执行加载更多
     */
    fun performPagingLoad() {
        if (footerLoadEnable && pagingHaveMore && !pagingLoading) {
            pagingLoading = true
            callback?.invoke()
        }
    }

}
